import { fetchEventSource } from "@microsoft/fetch-event-source";

class FatalError extends Error {}
class RetriableError extends Error {}

type ResultCallBack = (e: any | null) => void;

const BaseUrl = "http://localhost:8101/api/stream";
let isRequesting = false; // 状态标志

// 修改后的 postStreamChat 函数
export const postStreamChat = (
  author: string,
  onMessage: ResultCallBack,
  onError: ResultCallBack,
  onClose: ResultCallBack
) => {
  if (isRequesting) return; // 如果正在请求，则返回

  isRequesting = true; // 设置状态为请求中
  const ctrl = new AbortController();

  fetchEventSource(BaseUrl, {
    method: "GET", // 使用 GET 方法
    headers: {
      "Content-Type": "application/json",
    },
    signal: ctrl.signal,
    onmessage: onMessage,
    onerror: (err: any) => {
      onError(err);
      isRequesting = false; // 请求结束，重置状态
    },
    onclose: () => {
      onClose(null);
      isRequesting = false; // 请求结束，重置状态
    },
    onopen: async (response: any) => {
      if (response.ok) {
        return;
      } else if (
        response.status >= 400 &&
        response.status < 500 &&
        response.status !== 429
      ) {
        throw new FatalError();
      } else {
        throw new RetriableError();
      }
    },
    body: JSON.stringify({ prompt: author }), // 传递参数
  });
};

// 修改后的 getStreamChat 函数
export const getStreamChat = (
  author: string,
  onMessage: ResultCallBack,
  onError: ResultCallBack,
  onClose: ResultCallBack
) => {
  if (isRequesting) return; // 如果正在请求，则返回

  isRequesting = true; // 设置状态为请求中
  const ctrl = new AbortController();

  fetchEventSource(`${BaseUrl}?prompt=${encodeURIComponent(author)}`, {
    method: "GET",
    headers: {
      "Content-Type": "application/json",
    },
    signal: ctrl.signal,
    onmessage: onMessage,
    onerror: (err: any) => {
      onError(err);
      isRequesting = false; // 请求结束，重置状态
    },
    onclose: () => {
      onClose(null);
      isRequesting = false; // 请求结束，重置状态
    },
    onopen: async (response: any) => {
      if (response.ok) {
        return;
      } else if (
        response.status >= 400 &&
        response.status < 500 &&
        response.status !== 429
      ) {
        throw new FatalError();
      } else {
        throw new RetriableError();
      }
    },
  });
};
